#include "clientservice.h"

#include <QHostAddress>

ClientService::ClientService(int socketId, int state, QObject *parent):
    QTcpSocket(parent), serviceState(state)
{
    connect(this, SIGNAL(readyRead()),      this, SLOT(receDataFromClient()));
    connect(this, SIGNAL(disconnected()),   this, SLOT(disConnectSlot()));
    connect(this, SIGNAL(error(QAbstractSocket::SocketError)),
                                            this, SLOT(dispSocketError(QAbstractSocket::SocketError)));
    connect(&readTimer, SIGNAL(timeout()),  this, SLOT(receDataFromClient()));

    this->setSocketDescriptor(socketId);
    init();

    logger()->info("client:%1 connect to server\n", this->peerAddress().toString());

}

ClientService::~ClientService()
{
}

/*******************************************
  功能：发送LCD状态，包括设置LCD状态和当前状态，
    type = 0为设置LCD状态，type = 1为LCD当前状态
  参数：stateMap,状态表(<ID号，状态值> 状态:1,成功;0，失败;-1，此屏出问题)
  返回值：
  ******************************************/
void ClientService::sendSetLcdState(const QMap<qint16, qint8> &stateMap, const int type)
{
    qint32 len;
    qint16 header;
    qint8 cmd, eof;

    qint8 count;

    QByteArray stateBytes;
    QDataStream stateStream(&stateBytes, QIODevice::WriteOnly);
    stateStream.setVersion(QDataStream::Qt_4_6);

    count = qint8(stateMap.count());

    header = qint16(0xFFFA);
    len = qint32(9 + 3 * count);
    eof = qint8(0xFF);

    if (type == 0)
    {
        cmd = qint8(0x35);
    } else {
        cmd = qint8(0x39);
    }

    stateStream << header << len << cmd << count;

    QMapIterator<qint16, qint8> iterator(stateMap);
    while (iterator.hasNext()) {
        iterator.next();
        stateStream << iterator.key() << iterator.value();
    }

    stateStream << eof;

    this->write(stateBytes);
}



/*******************************************
  功能：初始化函数，初始化一些必要的参数
  参数：
  返回值：
  ******************************************/
void ClientService::init()
{
    isDataProUnfinish = false;
    isUpdateSer = false;
    isPause = false;
    isEndErr = true;
    isWantEnvirBright = false;
    isClientClose = false;
    isCheckLcdMode = false;

    receInfoList.clear();
    receInfoNum = 0;

    ReceInfoStruct receInfoStruct;
    receInfoStruct.file = new QFile(this);
    receInfoStruct.hasReceLen = 0;
    receInfoStruct.fileLen = 0;
    receInfoStruct.isFinish = false;
    receInfoStruct.pkgCount = 0;
    receInfoStruct.enmErr = TCPNOERR;
    receInfoStruct.DLTimer = new QTimer(this);
    receInfoList.append(receInfoStruct);

    halfBytes.clear();


//    QString str = QString::fromLocal8Bit("ClientService update===> %1").arg(serviceState);
//    emit sendDebugMsg(str);

    sendConnReply();
}


//========================= slot ====================================

/*******************************************
  功能：显示连接过程中出现所有错误的槽函数
  参数：QAbstractSocket::SocketError，错误类型
  返回值：
  ******************************************/
void ClientService::dispSocketError(QAbstractSocket::SocketError)
{
    logger()->warn(tr("connect err:%1\n").arg(this->errorString()));
}

/*******************************************
  功能：从客户端接收到数据的槽函数，调用processReceData()来处理
  参数：
  返回值：
  ******************************************/
void ClientService::receDataFromClient()
{
    QByteArray receBytes = this->readAll();

//    qDebug() << "receBytes============>" << receBytes.size();
    this->processReceData(receBytes);

}

/*******************************************
  功能：将数据写进缓存，一会发送出去
  参数：
  返回值：
  ******************************************/
inline qint64 ClientService::writeBytes(const QByteArray &data)
{
    if (isPause || isClientClose)
    {
        return 0;
    } else {
        qint64 size =  QTcpSocket::write(data);
        return size;
    }
}

/*******************************************
  功能：发送连接回复分析，只有第一次连接才有此回复，用来告诉客户端已经成功连接到服务端
  参数：
  返回值：
  ******************************************/
void ClientService::sendConnReply()
{
//    qDebug() << "---------------ClientService sendConnReply-----------------------";
    //客户端连接成功回复
    QByteArray connReplyBytes;
    QDataStream connReplyStream(&connReplyBytes,QIODevice::ReadWrite); //QIODevice::WriteOnly
    connReplyStream.setVersion(QDataStream::Qt_4_6);


    connReplyStream << qint16(0xFFFA);         //文件头
    connReplyStream << qint32(0x08);           //帧总长度
    connReplyStream << qint8(0x00);            //cmd 接收文件
    connReplyStream << qint8(0xff);

    this->writeBytes(connReplyBytes);

    QString str = QString::fromLocal8Bit("ClientService update===> %1").arg(serviceState);

    //如果serviceState大于等于0，则证明是更新后重新开户的服务端，
    //发送一个更新状态数据包过去
    if (serviceState >= 0)
    {
//        QString debMsg= tr("serviceState <<<<<<<<<<<<<<<<").arg(serviceState);
//        sendDebugMsg(debMsg);
        this->sendErrInfo(qint8(0xF2), (ERRENUM)(serviceState - 1), 0);
    }
}

/*******************************************
  功能：发送配置数据
  参数：configStruct，配置结构体
  返回值：
  ******************************************/
void ClientService::sendConfigData(qint8 cmd, const qint8 state)
{
    QByteArray configBytes;
    ConfigStruct configStruct;


    QDataStream configStream(&configBytes,QIODevice::WriteOnly);

    configStream.setVersion(QDataStream::Qt_4_6);

    //如果cmd为0x01则是发送服务的配置，如果是0X02则是发送服务器设置成功信息
    if (cmd == qint8(0x01))
    {
        configStream << qint16(0xFFFA);            //文件头
        configStream << qint32(0x44 + 90);         //帧总长度
        configStream << qint8(0x02);               //配置信息命令

        configStruct = configclass.getConfigStruct();

        qint16 year = configStruct.systemDate.year();
        qint8 month = configStruct.systemDate.month();
        qint8 day = configStruct.systemDate.day();

        qint8 hour = configStruct.systemTime.hour();
        qint8 minu = configStruct.systemTime.minute();
        qint8 second = configStruct.systemTime.second();

        qint8 scrollSpeed = configStruct.scrollSpeed;

        qint32 versionTYPE = configStruct.versionInfo.enVersionType;
        qint16 version1 = configStruct.versionInfo.version1;
        qint16 version2 = configStruct.versionInfo.version2;
        qint16 version3 = configStruct.versionInfo.version3;
        QString schedulePro = configStruct.versionInfo.schedulePro;     //播放列表项目名
        qint64 resourceSize = configStruct.versionInfo.resourceSize;    //播放资源大小

        qint32 bcInfoTime = configStruct.bcInfoTime;                    //播放本地信息时间
        qint32 isCollectPS = configStruct.isCollectPS;                  //是否收集环境光度

        configStream << configStruct.defaultLv;
        for(int i = 0; i < 4; i++)
        {
//            qDebug() << "i====>" << i;
            configStream << configStruct.lvStruct[i].lcdBirght << configStruct.lvStruct[i].envirStart << configStruct.lvStruct[i].envirEnd;
        }
//        qDebug() << "lvStruct..... end";

        configStream << configStruct.carNum;
        configStream << configStruct.carSide;
        configStream << year << month << day << hour << minu << second;
        configStream << scrollSpeed;

        configStream << configStruct.cpuLimmit;
        configStream << configStruct.memoryLimmit;
        configStream << configStruct.hardDiskLimmit;
        configStream << configStruct.limmit;
        configStream << configStruct.isReplortSlcd;
        configStream << configStruct.isMastDev;
        configStream << versionTYPE << version1 << version2 << version3 << resourceSize;

        configStream << bcInfoTime << isCollectPS;

        uint namelen = 62;

        char *pSchedule = (char *)malloc(sizeof(char) * 63);

        strcpy(pSchedule, schedulePro.toLatin1().data());
        configStream.writeBytes(pSchedule, namelen);

        free(pSchedule);
        //保留数据位12
        for (int i = 0; i < 6; i++)
        {
            configStream << qint16(0);
        }
    } else {
        //发送设置完成包
        configStream << qint16(0xFFFA);            //文件头
        configStream << qint32(0x09);              //帧总长度

        if (cmd == qint8(0x07))
        {
            configStream << qint8(0x07);               //配置信息命令
        } else if (cmd == qint8(0x08))
        {
            configStream << qint8(0x08);               //配置信息命令
        } else if (cmd == qint8(0x04)){

            configStream << qint8(0x05);                //配置信息命令
        }
        if (state >= 1)
        {
            configStream << qint8(state);               //如果执行成功,那么返回0x01
        } else {
            configStream << qint8(state);               //如果执行失败，那么返回0xFF
        }
    }

    configStream << qint8(0xFF);         //帧尾

    //如果发送数据小于要发送数据包大小，那么得重新发送
    if (configBytes.size() < (this->writeBytes(configBytes)))
    {
       this->writeBytes(configBytes);
    }
    this->flush();

}

/*******************************************
  功能：发送LCD ID列表
  参数：
  返回值：
  ******************************************/
void ClientService::sendLcdIDList()
{
    QList<PanelInfoStruct> panelInfoList = configclass.getSLCDInfoIntList();

    QByteArray IDBytes;
    QDataStream IDStream(&IDBytes,QIODevice::WriteOnly);
    IDStream.setVersion(QDataStream::Qt_4_6);

    qint32 len;
    qint16 header, ID;
    qint8 count, cmd, eof;

    count = qint8(panelInfoList.count());
    header = qint16(0xFFFA);
    len = qint32(9 + 4 * count);
    cmd = qint8(0x32);
    eof = qint8(0xFF);

    IDStream << header << len << cmd << count;
    for(qint8 i = 0; i < count; i++)
    {
        ID = qint16(panelInfoList.at(i).panelID);
        qint16 isCollect = qint16(panelInfoList.at(i).isCollect);
        IDStream << ID << isCollect;
    }
    IDStream << eof;

    this->writeBytes(IDBytes);

}

/*******************************************
  功能：发送文件数据错误信息
  参数：fileName，发送的文件名
  返回值：
  ******************************************/
void ClientService::sendErrInfo(qint8 type, ERRENUM error, const QString &fileName)
{


    //文件发送完成回复,如果有错误则在错误标志位给出错误编号
    QByteArray errBytes;
    QDataStream errStream(&errBytes,QIODevice::ReadWrite); //QIODevice::WriteOnly
    errStream.setVersion(QDataStream::Qt_4_6);

    qint16 header = qint16(0xFFFA);
    qint32 pkglen = qint32(0x005C);
    qint8 cmd = qint8(0xFE);
    qint8 qintType = qint8(type);
    qint8 err = error;
    qint8 eof = qint8(0xFF);
    qint16 retain = qint16(0x00);

    uint fileNameLen = 48;

    char *pFileName = (char *)malloc(sizeof(char) * 49);


    if (type == qint8(0xF1))
    {
        if (receInfoList.at(receInfoNum).hasReceLen < receInfoList.at(receInfoNum).fileLen ||
                receInfoList.at(receInfoNum).pkgCount != receInfoList.at(receInfoNum).recePkgMap.count())
        {
            err = 0x03;
        } else {
            emit serviceInfoSignal(receInfoList.at(receInfoNum).fileName, receInfoList.at(receInfoNum).fileLen);

        }
    }

    errStream << header << pkglen << cmd << qintType << err;
    if (fileName.isEmpty())
    {
        for(int i = 0; i < 26; i++)
        {
            errStream << retain;
        }
    } else {
        strcpy(pFileName, fileName.toLatin1().data());
        errStream.writeBytes(pFileName, fileNameLen);
    }

    for(int i = 0; i < 15; i++)
    {
        errStream << retain;
    }

    errStream << eof;

    free(pFileName);
    this->writeBytes(errBytes);
}



/*******************************************
  功能：发送下载更新服务端文件的状态
  参数：err，错误编号
  返回值：
  ******************************************/
//void ClientService::sendSerFileState(qint8 err)
//{

//    if (receInfoList.at(receInfoNum).hasReceLen < receInfoList.at(receInfoNum).fileLen ||
//            receInfoList.at(receInfoNum).pkgCount != receInfoList.at(receInfoNum).recePkgMap.count())
//    {
//        err = 0x03;
//    } else {
//        qDebug() << receInfoList.at(receInfoNum).fileName << "============ sendSerFileState finish  success ===============" << receInfoList.at(receInfoNum).fileLen << receInfoList.at(receInfoNum).hasReceLen;
//        emit serviceInfoSignal(receInfoList.at(receInfoNum).fileName, receInfoList.at(receInfoNum).fileLen);

//    }

//    //文件发送完成回复
//    QByteArray finishDate;
//    QDataStream finishStream(&finishDate,QIODevice::ReadWrite); //QIODevice::WriteOnly
//    finishStream.setVersion(QDataStream::Qt_4_6);

//    //如果更新完成，即flag = 0x02;
//    qint8 flag = 0x01;

//    finishStream << qint16(0xFFFA);         //文件头
//    finishStream << qint32(0x28);           //帧总长度
//    finishStream << qint8(0xF2);            //cmd 接收文件
//    finishStream << err;                    //错误标志,无错误为0
//    finishStream << flag;                   //开始标志 暂时保留
//    finishStream << qint8(0xff);

//    this->write(finishDate);

//    if (err == 0)
//    {
//        isUpdateSer = false;
//    }
//}

/*******************************************
  功能：发送文件的数据,先发送一个文件下载请求回复，然后将一个文件切成一定数据大小等同的数据包
       一个一个发送过去，最后发送一个下载完成
  参数：fileName，要发送的文件名;pos,文件位置
  返回值：正确返回tur,错误返回false
  ******************************************/
bool ClientService::sendFileData(char *fileName, const qint64 pos)
{
//    if (!isUpdateSer)
//    {
//        isPause = false;
//    }
    QByteArray sendBytes;
    uint fileNameLen = 44;
    int writeSize;

    quint32 filelen, currentSize, bytesToWrite;

    QString sendFilePath = tr("%1/%2").arg(g_NotePath).arg(fileName);

    //发送下载回复
    QDataStream sendStream(&sendBytes,QIODevice::WriteOnly);

    sendStream.setVersion(QDataStream::Qt_4_6);

    sendStream << qint16(0xFFFA);         //文件头
    sendStream << qint32(0x3e);           //帧总长度
    sendStream << qint8(0x12);            //cmd 接收文件
    //文件名字
    sendStream.writeBytes(fileName, fileNameLen);
    sendStream << qint8(0x00);            //错误标志 暂时保留
    sendStream << qint8(0x01);            //开始标志 暂时保留


    //打开要发送的文件，如果打开不了，则发送一个错误信号，然后返回false
    QFile sendFile(sendFilePath);
    if (sendFile.exists())
    {
        if (!sendFile.open(QFile::ReadOnly))
        {
            ERRENUM err = OPENERR;
            sendErrInfo(qint8(0x12), err, fileName);
            return false;
        }
    } else {
        ERRENUM err = NOFILE;
        sendErrInfo(qint8(0x12), err, fileName);
        return false;
    }


    filelen = sendFile.size();
    sendStream << filelen;
    sendStream << qint8(0xff);

    //传送文件前将文件信息打包发送
    this->writeBytes(sendBytes);
//    qDebug() << sendBytes.size() << "send start pkg--------------------";

    //接下来开始正式的文件打包传送
    int currentSendSize;
    qint32 pkglen, pkgNum, pkgCount, sentSize, retain;
    qint64 positon = 0;

    currentSendSize = FILEPKGSIZE;
    if (filelen % currentSendSize != 0)
    {
        pkgCount = filelen / currentSendSize + 1;
    } else {
        pkgCount = filelen / currentSendSize;
    }

    pkglen = 0;
    pkgNum = 0;
    sentSize = 0;
    retain = 0;
    //readTimer.start(1000);

    currentSendSize = FILEPKGSIZE;

    if (pos)
    {
        sendFile.seek(pos);
    }

    int i = 0;

    //正式开始发送文件包 ,pkgNum从1开始
    do{

//        qDebug() << "................>>>>" << pkgNum << pkgCount;
        if (this->bytesAvailable() >= 0x08)
        {
//            qDebug() << "this->bytesAvailable()............." << this->bytesAvailable();
            this->receDataFromClient();
        }

        if (isPause || isClientClose)
        {
            return false;
        }

        i++;

        QByteArray fileData;
        fileData.clear();

        QDataStream fileStream(&fileData,QIODevice::ReadWrite); //QIODevice::WriteOnly
        fileStream.setVersion(QDataStream::Qt_4_6);
        pkgNum ++;

        bytesToWrite = filelen - sentSize;

        //看文件剩下的数据和固定数据大小哪个小，即发送小的那个数据量
        currentSize = qMin(quint32(currentSendSize), bytesToWrite);

        //因为发送数据时，writeBytes()写时数据时，它会添加一个4个字节的所写数据的大小，
        //所以数据包的总大小应该加上4
        pkglen = 88 + currentSize + 4;

        fileStream << qint16(0xFFFA);
        fileStream << pkglen;

        fileStream << qint8(0x12);  //cmd

        //每次都把文件名字发送出去
        fileStream.writeBytes(fileName, fileNameLen);

        fileStream << pkgCount;
        fileStream << pkgNum;
        fileStream << currentSendSize;
        fileStream << sentSize;
        fileStream << filelen;

        QByteArray bytes = sendFile.read(currentSize);
        fileStream.writeBytes(bytes, currentSize);
        fileStream << positon;

        positon = sendFile.pos();

        //        if (i == 6)
        //        {
        //            sentSize += currentSize;
        //            continue;
        //        }

        fileStream << retain;
        fileStream << qint8(0xFF);

        //将文件读取到的数据写到要发送的数据中
        writeSize = this->writeBytes(fileData);
        sentSize += currentSize;

        //因为Qt的发送机制是将数据都存贮在缓冲区中，等空闲的时候再发送过去
        //所以如果此时出现断开等错误情况，那么数据有可能一个都没发送出去
        //flush()则是将缓冲区中的数据发送出现，但可能会让运行效率有所降低
        if (i > 7)
        {
            this->flush();
//            this->waitForBytesWritten(0.1);
//            this->waitForReadyRead(0.1);
            i = 0;
        }

    } while(currentSize >= FILEPKGSIZE);

    readTimer.stop();

    //文件发送完成回复
    QByteArray finishDate;
    QDataStream finishStream(&finishDate,QIODevice::ReadWrite); //QIODevice::WriteOnly
    finishStream.setVersion(QDataStream::Qt_4_6);

    finishStream << qint16(0xFFFA);         //文件头
    finishStream << qint32(0x3e);           //帧总长度
    finishStream << qint8(0x13);            //cmd 接收文件
    finishStream << qint8(0x00);            //错误标志 暂时保留
    finishStream << qint8(0x02);            //开始标志 暂时保留

    finishStream.writeBytes(fileName, fileNameLen);
    finishStream << filelen;
    finishStream << qint8(0xff);

    this->write(finishDate);
    sendFile.close();

    return true;
}

/*******************************************
  功能：发送丢失的数据包
  参数：lostPkgStruct，丢失数据包结构体
  返回值：
  ******************************************/
void ClientService::sendUnfinishFile(const QString &fileName, const QList<FilePkgStruct> unSendPkgList)
{

    qint32 pkglen, pkgNum, retain, filelen;
    qint16 header;
    qint8 cmd, eof;

    qint64 position;
    qint32 currentSendSize;
    uint filenamelen = 48;

    header = qint32(0xFFFA);
    retain = qint32(0xAAAA);
    cmd = qint8(0x15);
    eof = qint8(0xFF);

    char *p = (char *)malloc(sizeof(char) * 49);
    QString sendFilePath = tr("%1/%2").arg(g_NotePath).arg(fileName);

    QFile sendFile(sendFilePath);
    if (sendFile.exists())
    {
        if (!sendFile.open(QFile::ReadOnly))
        {
            ERRENUM err = OPENERR;
            sendErrInfo(qint8(0x15), err, fileName);
            return;
        }
    } else {
        ERRENUM err = NOFILE;
        sendErrInfo(qint8(0x15), err, fileName);
        return;
    }

//    int i = 0;
//    int j = 0;

    filelen = sendFile.size();

//    while(iterator.hasNext())
//    {
//        iterator.next();

    for(int i = 0; i < unSendPkgList.count(); i++)
    {
        FilePkgStruct filePkgStruct = unSendPkgList.at(i);
        int k = 0;
        for(int j = filePkgStruct.start; j <= filePkgStruct.end; j++)
        {
            k++;
            if (isPause || isClientClose)
            {
                return;
            }

            memset(p, 0, 49);
            QByteArray lostPkgBytes;

            //发送下载回复
            QDataStream lostPkgStream(&lostPkgBytes,QIODevice::WriteOnly);
            lostPkgStream.setVersion(QDataStream::Qt_4_6);
//            pkgNum = iterator.key();
            pkgNum = j;

            if (j == filePkgStruct.start)
            {
                sendFile.seek(filePkgStruct.startPos);
            }

            currentSendSize = FILEPKGSIZE;
            pkglen = 76 + currentSendSize + 8;

            lostPkgStream << header;
            lostPkgStream << pkglen;
            lostPkgStream << cmd;

            strcpy(p, fileName.toLatin1().data());
            lostPkgStream.writeBytes(p, filenamelen);
            lostPkgStream << pkgNum;
            lostPkgStream << currentSendSize;

            position = sendFile.pos();

            QByteArray bytes = sendFile.read(currentSendSize);
            lostPkgStream.writeBytes(bytes, currentSendSize);

            lostPkgStream << position;
            lostPkgStream << retain;
            lostPkgStream << eof;
    //        if (i == 3)
    //        {
    //            continue;
    //        }

            this->writeBytes(lostPkgBytes);

            if (k == 7)
            {
                this->flush();
                if (this->waitForReadyRead(1))
                {
//                    qDebug() << "====================== waitForReadyRead ===========================";
                    this->receDataFromClient();
                }
                k = 0;
            }
        }
    }

}

/*******************************************
  功能：发送维护终端申请的日志文件信息
  参数：
  返回值：
  ******************************************/
void ClientService::sendFileInfoList(const qint32 startDate, const qint32 endDate)
{
    qint8 cmd;

    //发送下载回复
    QByteArray sendBytes;
    QDataStream sendStream(&sendBytes,QIODevice::ReadWrite);
    sendStream.setVersion(QDataStream::Qt_4_6);

    quint32 filelen, modifiedDate, modifiedTime;
    char *fileName = (char *)malloc(sizeof(char) * 49);
    uint fileNameLen = 44;

    int fileCount;

    QDir dir(g_NotePath);
    dir.setFilter(QDir::Files);
    dir.setSorting(QDir::Name);

    QFileInfoList list = dir.entryInfoList();
    fileCount = list.count();

    //文件检测
    for(int i = 0; i < fileCount; i++)
    {
        QFileInfo fileInfo = list.at(i);
        qint32 creatDate = fileInfo.created().toString("yyyyMMdd").toInt();

        if (creatDate < startDate || creatDate > endDate)
        {
            list.removeAt(i);
            i--;
            fileCount--;
        }
    }

    fileCount = list.count();

    int sendCount = 0;
    int hasSentCount = 0;

    while (fileCount > 0)
    {
        //如果文件数据大于20，将分成多次发送
        if (fileCount >= 20)
        {
            sendCount = 20;
            fileCount = fileCount - 20;
        } else {
            sendCount = fileCount;
            fileCount = 0;
        }

        if (hasSentCount == 0)
        {
            cmd = qint8(0x0A);
        } else {
            cmd = qint8(0x0B);
        }

        sendStream << qint16(0xFFFA);                       //文件头
        sendStream << qint32(9 + sendCount * 60);           //帧总长度
        sendStream << cmd;                                  //cmd 接收文件
        sendStream << qint8(sendCount);

        //循环将每一个文件的作息进行到sendBytes中
        for (int i = hasSentCount; i < (hasSentCount + sendCount); ++i) {
            QFileInfo fileInfo = list.at(i);

            QString strFileName = fileInfo.fileName();

            memset(fileName, 0, 49);
            strncpy(fileName, strFileName.toLocal8Bit(), 48);

            sendStream.writeBytes(fileName, fileNameLen);
            filelen = fileInfo.size();
            modifiedDate = fileInfo.lastModified().toString("yyyyMMdd").toInt();
            modifiedTime = fileInfo.lastModified().toString("hhmmss").toInt();

            sendStream << filelen;
            sendStream << modifiedDate;
            sendStream << modifiedTime;
        }

        hasSentCount += sendCount;
        sendStream << qint8(0xFF);
        sendStream.skipRawData((9 + sendCount * 60) * -1);


        this->write(sendBytes);
        sendBytes.clear();
        //这里必须是-1，不然当发送第二次文件信息数据时会将数据头0xFFFA变成0x00FA
        sendBytes.resize(-1);
    }

    //发送文件信息完成包
    QByteArray finishBytes;
    QDataStream finishStream(&finishBytes,QIODevice::ReadWrite);
    finishStream.setVersion(QDataStream::Qt_4_6);
    finishStream << qint16(0xFFFA);            //文件头
    finishStream << qint32(0x08);              //帧总长度
    finishStream << qint8(0x0C);               //配置信息命令
    finishStream << qint8(0xFF);               //配置信息命令

    this->write(finishBytes);
}

/*******************************************
  功能：分析接收到的配置信息数据
  参数：receData，接收到的配置信息
  返回值：
  ******************************************/
void ClientService::analysisConfigData(const QByteArray &receData)
{

    qint8 state = 1;
    qint16 header;
    qint32 len;
    qint8 cmd, retain, eof;

    qint16 defaultLv, cpuLimmit, memoryLimmit, hardDiskLimmit, limmit;

    qint16 carriageNum, carSide, isReportSlcd;
    qint16 year;
    quint8 month, day, hour, minute, second, scrollSpeed;

    qint32 bcInfoTime;                      //播放本地信息时间
    qint32 isCollectPS;                     //是否收集环境光度

    ConfigStruct configStruct;
    configStruct.isMastDev = -1;
    configStruct.masterDevIp = "";
    configStruct.isReplortSlcd = -1;
    configStruct.logReserveDays = -1;

    LcdBriLVStruct lvStruct[4];

    QString strDate;
    QString strTime;

    QByteArray receBytes = receData;

    QDataStream configStream(receBytes);
    configStream.setVersion(QDataStream::Qt_4_6);

    configStream >> header >> len >> cmd;

    //如果cmd为0x04,则证明是设置配置命令
    if (cmd == qint8(0x04) || cmd == qint8(0x07))
    {
        configStream >> defaultLv;
        for(int i = 0; i < 4; i++)
        {
            configStream >> lvStruct[i].lcdBirght >> lvStruct[i].envirStart >> lvStruct[i].envirEnd;
        }
        configStream >> carriageNum >> carSide;
        configStream >> year >> month >> day >> hour >> minute >> second >> scrollSpeed;
        configStream >> cpuLimmit >> memoryLimmit >> hardDiskLimmit >> limmit;
        configStream >> isReportSlcd >> bcInfoTime >> isCollectPS;
        for(int i = 0; i < 12; i++)
        {
            configStream >> retain;
        }
    }

    configStream >> eof;

    if (eof != qint8(0xFF))
    {
        isDataProUnfinish = true;
        halfBytes.clear();
        halfBytes = receBytes;
    }

    //如果cmd为0x04,则是设置服务端的配置信息
    if (cmd == qint8(0x04) || cmd == qint8(0x07))
    {
//        strColor = tr("%1:%2:%3").arg(red).arg(blue).arg(green);
        strDate = tr("%1.%2.%3").arg(year).arg(month).arg(day);
        strTime = tr("%1:%2:%3").arg(hour).arg(minute).arg(second);
        QString monthFormat;
        QString dayFormat;
        if(month >= 10)
        {
            monthFormat = "MM";
        } else {
            monthFormat = "M";
        }
        if(day >= 10)
        {
            dayFormat = "dd";
        } else {
            dayFormat = "d";
        }
        QString dateFormat = tr("yyyy.%1.%2").arg(monthFormat).arg(dayFormat);

        configStruct.defaultLv = defaultLv;
        for(int i = 0; i < 4; i++)
        {
            configStruct.lvStruct[i] = lvStruct[i];
        }

        configStruct.carNum = carriageNum;
        configStruct.carSide = carSide;
        configStruct.systemDate = QDate::fromString(strDate, dateFormat);
        configStruct.systemTime = QTime::fromString(strTime, "h:m:s");
        configStruct.scrollSpeed = scrollSpeed;
        configStruct.cpuLimmit = cpuLimmit;
        configStruct.memoryLimmit = memoryLimmit;
        configStruct.hardDiskLimmit = hardDiskLimmit;
        configStruct.limmit = limmit;
        configStruct.isReplortSlcd = isReportSlcd;
        configStruct.bcInfoTime = bcInfoTime;
        configStruct.isCollectPS = isCollectPS;

        //通过配置模块设置服务端的配置信息
        if (configclass.setConfig(configStruct))
        {
            logger()->info("client:%1 update configration\n", this->peerAddress().toString());
            emit updateConfig();
        }
        if (cmd == qint8(0x07))
        {
            state = configclass.saveAsDefaultconfig();

            if (state >= 1)
            {
                logger()->info("client:%1 success to save default configration\n", this->peerAddress().toString());
            } else {
                logger()->info("client:%1 fail to save default configration\n", this->peerAddress().toString());
            }
        }
    } else if (cmd == 0x08)
    {
        state = configclass.restoreDefaultConfig();

        if (state >= 1)
        {
            logger()->info("client:%1 success to restore default configration\n", this->peerAddress().toString());
        } else {
            logger()->info("client:%1 fail to restore default configration\n", this->peerAddress().toString());
        }
    }

    if (cmd == qint8(0x08))
    {
        this->sendConfigData(0x01, 1);
    }
    this->sendConfigData(cmd, state);

    //如果数据包还未处理完成，那么将解析过的数据删除，继续解析剩下的数据
    if (receBytes.size() > len)
    {
        isDataProUnfinish = false;
        receBytes.remove(0, len);
        this->processReceData(receBytes);
        return;
    }


}


void ClientService::changeLocalDateTime(const QByteArray& receData)
{

    qint16 header;
    qint32 len;
    qint8 cmd, retain, eof;
//    qint32 transformValue;

    qint16 defaultLv, cpuLimmit, memoryLimmit, hardDiskLimmit, limmit;

//    quint8 red, blue, green, colorRetain;
    qint16 carriageNum, carSide;
    qint16 year;
    quint8 month, day, hour, minute, second, scrollSpeed;

    ConfigStruct configStruct;
    LcdBriLVStruct lvStruct[4];

//    QString strColor;
    QString strDate;
    QString strTime;

    QByteArray receBytes = receData;

    QDataStream configStream(receBytes);
    configStream.setVersion(QDataStream::Qt_4_6);

    configStream >> header >> len >> cmd;

    //如果cmd为0x04,则证明是设置配置命令
    if (cmd == qint8(0x0d))
    {
        configStream >> defaultLv;
//        configStream >> contras >> red >> blue >> green >> colorRetain >> transformValue;
        for(int i = 0; i < 4; i++)
        {
            configStream >> lvStruct[i].lcdBirght >> lvStruct[i].envirStart >> lvStruct[i].envirEnd;
        }
        configStream >> carriageNum >> carSide;
        configStream >> year >> month >> day >> hour >> minute >> second >> scrollSpeed;
        configStream >> cpuLimmit >> memoryLimmit >> hardDiskLimmit >> limmit;
        for(int i = 0; i < 12; i++)
        {
            configStream >> retain;
        }
    }

    configStream >> eof;

    if (eof != qint8(0xFF))
    {
        isDataProUnfinish = true;
        halfBytes.clear();
        halfBytes = receBytes;
    }

    //如果cmd为0x04,则是设置服务端的配置信息
    if (cmd == qint8(0x0D))
    {
        strDate = tr("%1.%2.%3").arg(year).arg(month).arg(day);
        strTime = tr("%1:%2:%3").arg(hour).arg(minute).arg(second);
        QString monthFormat;
        QString dayFormat;
        if(month >= 10)
        {
            monthFormat = "MM";
        } else {
            monthFormat = "M";
        }
        if(day >= 10)
        {
            dayFormat = "dd";
        } else {
            dayFormat = "d";
        }
        QString dateFormat = tr("yyyy.%1.%2").arg(monthFormat).arg(dayFormat);

        configStruct.defaultLv = defaultLv;


        for(int i = 0; i < 4; i++)
        {
            configStruct.lvStruct[i] = lvStruct[i];
        }

//        qDebug() << "set DateTime >>>>>>>>>>>>>>>>>>>>";
        configStruct.carNum = carriageNum;
        configStruct.carSide = carSide;
        configStruct.systemDate = QDate::fromString(strDate, dateFormat);
        configStruct.systemTime = QTime::fromString(strTime, "h:m:s");
        configStruct.scrollSpeed = scrollSpeed;
        configStruct.cpuLimmit = cpuLimmit;
        configStruct.memoryLimmit = memoryLimmit;
        configStruct.hardDiskLimmit = hardDiskLimmit;
        configStruct.limmit = limmit;


#ifdef _TTY_POSIX_

        //设置系统时间
        QString dateStr = QObject::tr("date -s %1/%2/%3").arg(month).arg(day).arg(year);
        QString timeStr = QObject::tr("date -s %1:%2:%3").arg(hour).arg(minute).arg(second);


        int setDate = system(dateStr.toLatin1().data());
        int setTime = system(timeStr.toLatin1().data());

        system("hwclock -w");
#else
        int setDate = -1;
        int setTime = -1;
#endif
        QByteArray replyBytes;

        if (setDate == 0 && setTime == 0)
        {
//            qDebug() << "errno..11." << strerror(errno);
            logger()->info("client:%1 success to update system date and time\n", this->peerAddress().toString());
        } else {
//            qDebug() << "errno..22." << strerror(errno);

            logger()->info("client:%1 fail to update system date and time\n", this->peerAddress().toString());
        }


        QDataStream replyStream(&replyBytes,QIODevice::WriteOnly);


        replyStream << qint16(0xFFFA);            //文件头
        replyStream << qint32(0x10);              //帧总长度
        replyStream << qint8(0x0d);               //配置信息命令

        //如果cmd为0x01则是发送服务的配置，如果是0X02则是发送服务器设置成功信息

        replyStream << qint32(setDate) << qint32(setTime);

        replyStream << qint8(0xFF);

        this->writeBytes(replyBytes);

//        qDebug() << "dateStr" << dateStr << timeStr;
//        qDebug() << "setDate" << setDate << setTime;

    }

    //如果数据包还未处理完成，那么将解析过的数据删除，继续解析剩下的数据
    if (receBytes.size() > len)
    {
        isDataProUnfinish = false;
        receBytes.remove(0, len);
        this->processReceData(receBytes);
        return;
    }

}

/*******************************************
  功能：分析日记文件请求列表
  参数：receData，接收到的配置信息
  返回值：
  ******************************************/

void ClientService::analysisNoteFileInfoData(const QByteArray& receData)
{
    qint16 header;
    qint8 cmd, eof;
    qint32 len, startDate, endDate;

    QByteArray receBytes = receData;

    QDataStream applyStream(receBytes);
    applyStream.setVersion(QDataStream::Qt_4_6);

    applyStream >> header >> len >> cmd;

    applyStream >> startDate >> endDate;

    applyStream >> eof;

    if (eof != qint8(0xFF) && applyStream.atEnd())
    {
        isDataProUnfinish = true;
        halfBytes.clear();
        halfBytes = receBytes;

//        QFile file(ERR01PATH);
//        file.open(QFile::WriteOnly);
//        file.write(halfBytes);
//        file.close();
    }

    //如果数据包还未处理完成，那么将解析过的数据删除，继续解析剩下的数据
    if (receBytes.size() > len)
    {
        isDataProUnfinish = false;
        receBytes.remove(0, len);
        this->processReceData(receBytes);
        return;
    } else {
        this->sendFileInfoList(startDate, endDate);
    }


}

/*******************************************
  功能：分析接收到的文件包数据
  参数：receData，接收到的文件包数据
  返回值：
  ******************************************/
bool ClientService::analysisFileData(QByteArray &receBytes)
{
//    qDebug() << "analysisFileData=============>>>" << receBytes.size();
    qint64 pos;
    qint32 hasReceLen, fileLen, pkglen, pkgCount, pkgNum, sentSize, retain;
    qint16 header;
    uint currentSize, fileNameLen;
    qint8 error, flag, eof, cmd;
    QString fileName;

    //创建一个 QByteArray 来存贮传过来的文件数据
    QByteArray fileBytes;

    //剩余数据大小
    uint leftSize = receBytes.size();
    //传送过来的数据总大小
    uint receSize = receBytes.size();

    char *pFileName = (char *)malloc(sizeof(char) * 49);
    hasReceLen = receInfoList[receInfoNum].hasReceLen;
    fileLen = 0;
    fileNameLen = 48;

    QDataStream receStream(&receBytes, QIODevice::ReadOnly);
    receStream.setVersion(QDataStream::Qt_4_6);

    //如果是文件还未打开，即证明这是一个新的文件下载请求，
    //收到的第一个数据包是下载文件请求回复包
    receStream >> header >> pkglen >> cmd;

    if (pkglen == qint32(0x3e))
    {
//        qDebug() << ".......pkglen == qint32(0x3e)pkglen == qint32(0x3e)..........." ;
        receStream.readBytes(pFileName, fileNameLen);
        receStream >> error >> flag;
        receStream >> fileLen;
        receStream >> eof;

        leftSize = leftSize - pkglen;
        fileName = pFileName;

        qDebug() << fileName <<  0xFF << eof << ".......pkglen == qint32(0x3e)pkglen == qint32(0x3e)..........." ;
//        if (!receInfoList[receInfoNum].fileName.isEmpty() && receInfoList[receInfoNum].fileName != fileName)
//        {
//            this->analysisFileChange(fileName);
//        }

        //下载中的文件会加一个后缀.download
        //比如file->file.download
        QString downLoadFileName;
        if (isUpdateSer)
        {
            downLoadFileName = tr("%1/%2/%3").arg(g_installPath).arg(UPDATEPATH).arg(pFileName);
//            qDebug() << "downLoadFileName=============>>" << downLoadFileName;
        } else {
            downLoadFileName = tr("%1/%2").arg(g_NotePath).arg(pFileName);
//            qDebug() << "noteName=============>>" << downLoadFileName;

        }
        downLoadFileName.append(".download");

        //文件信息进行初始化
        receInfoList[receInfoNum].fileName = pFileName;
        receInfoList[receInfoNum].fileLen = fileLen;
        receInfoList[receInfoNum].isFinish = false;
        receInfoList[receInfoNum].enmErr = TCPNOERR;
        receInfoList[receInfoNum].file->setFileName(downLoadFileName);

        hasReceLen = 0;

        //如果此时文件打开失败，即在名字后面加一横线和数据
        //比如，file.pkg.download->file-1.download
        int num = 1;
        QString filePath;
        if (!receInfoList[receInfoNum].file->isOpen())
        {
            while(!receInfoList[receInfoNum].file->open(QIODevice::WriteOnly))
            {
                QString strNum = (tr("-%1").arg(num));
                if (fileName.contains("."))
                {
                    int index = fileName.indexOf(".");
                    fileName.insert(index, strNum);
                } else {
                    fileName.append(strNum);
                }

                num ++;
                fileName.append(".download");
                filePath = tr("%1/%2").arg(g_NotePath).arg(fileName);

                receInfoList[receInfoNum].file->setFileName(filePath);
            }
            receInfoList[receInfoNum].filePath = filePath;
        }
    } else{
        receStream.skipRawData(-1 * 7);
    }

    int i = 0;
    fileNameLen = 44;

//    qDebug() << " receInfoList[receInfoNum].file" <<  receInfoList[receInfoNum].fileName;

    while (!receStream.atEnd())
    {
        i++;
        currentSize = 0;
        receStream >> header >> pkglen >> cmd;

//        qDebug() << fileName << "..." << pkglen << cmd;

        if (cmd != qint8(0x12) && cmd != 0)
        {
            receBytes.remove(0, receSize - leftSize);
            this->processReceData(receBytes);
            return true;
        }

        //把文件名读出来
        receStream.readBytes(pFileName, fileNameLen);
        receStream >> pkgCount >> pkgNum >> currentSize >> sentSize >> fileLen;

        fileName = pFileName;
        //清空上一次的数据，设定大小，将文件数据存放到fileBytes中
        fileBytes.clear();
        if (currentSize < 2000)
        {
            fileBytes.resize(currentSize);
        }

        receStream >> fileBytes;
        receStream >> pos;
        receStream >> retain;
        receStream >> eof;

        //如果结束标志不对，则证明一个包被分成2次发送，那么将这半个包先存贮起来，
        //下一次收取数据时再重新合并
        if (eof != qint8(0xFF))
        {
//            qDebug() << "eof != qint8(0xFF)" << eof;
            free(pFileName);
            isDataProUnfinish = true;
            halfBytes.clear();
            receBytes.remove(0, receSize - leftSize);
            halfBytes = receBytes;
//            if (isEndErr)
//            {
//                isEndErr = false;
//                QFile file(ERR01PATH);
//                file.open(QFile::WriteOnly);
//                file.write(receBytes);
//                file.close();
//            }
            return true;
        }

//        if (receInfoList[receInfoNum].fileName != pFileName)
//        {
//            this->analysisFileChange(fileName);
//        }

        //将每一次的数据写进文件中，当收到数据 >= 文件长度，则证明文件读取完成
        receInfoList[receInfoNum].pkgCount = pkgCount;
        receInfoList[receInfoNum].file->seek(pos);

        receInfoList[receInfoNum].fileLen = fileLen;

        int nWrite = receInfoList[receInfoNum].file->write(fileBytes);
        receInfoList[receInfoNum].recePkgMap.insert(pkgNum, receInfoList[receInfoNum].file->pos());

        hasReceLen = receInfoList[receInfoNum].hasReceLen + nWrite;
        receInfoList[receInfoNum].hasReceLen = hasReceLen;

        emit downLoadProgress(receInfoList[receInfoNum].fileName, hasReceLen);
        leftSize = leftSize - pkglen;
    }

    free(pFileName);

//    if (receInfoList[receInfoNum].fileLen != 0 && receInfoList[receInfoNum].fileLen <= receInfoList[receInfoNum].hasReceLen)
//    {
//        this->checkFileFinish(receInfoList[receInfoNum].fileName);
//    }

    //如果数据包还未处理完成，那么将解析过的数据删除，继续解析剩下的数据
    if (!receStream.atEnd())
    {
        isDataProUnfinish = false;
        receBytes.remove(0, receSize - leftSize);

        this->processReceData(receBytes);
    }
//     qDebug() << "999 ====================>";

    return true;
}

/*******************************************
  功能：分析接收到的文件包数据
  参数：receData，接收到的文件包数据
  返回值：
  ******************************************/
void ClientService::analysisUnfinishPkg(QByteArray &receData)
{
//    qDebug() << "====================================>>analysisUnfinishPkg";

//    LostPkgStruct lostPkgStruct;
    QList<FilePkgStruct> unSendPkgList;
    FilePkgStruct unSendPkgStruct;

    qint64 position;
    qint32 pkglen, lostPkgCount, startNum, endNum;
    qint16 header;
    qint8 cmd, eof, finishFlag;
    uint fileNameLen = 48;
    char *pFileName = (char *)malloc(sizeof(char) * 49);

    QByteArray receBytes = receData;
    QDataStream lostPkgStream(&receBytes,QIODevice::ReadOnly);
    lostPkgStream.setVersion(QDataStream::Qt_4_6);

    pkglen = qint32(0x00);

    lostPkgStream >> header >> pkglen >> cmd;

    //如果数据包还未处理完成，那么将解析过的数据删除，继续解析剩下的数据
    if (receData.size() < pkglen)
    {
        isDataProUnfinish = true;

        halfBytes.clear();
        halfBytes = receBytes;
        isEndErr = false;
        return ;
    }
    lostPkgStream.readBytes(pFileName, fileNameLen);
    lostPkgStream >> lostPkgCount;
//    lostPkgStruct.fileName = pFileName;
    QString fileName = pFileName;

    free(pFileName);

    if (receData.size() < pkglen && pkglen != 0)
    {
        isDataProUnfinish = true;
        halfBytes.clear();
        halfBytes = receData;
    }
    for(int i = 0; i < lostPkgCount; i++)
    {
//        lostPkgStream >> pkgNum >> position;
//        lostPkgStruct.lostPkgMap.insert(pkgNum, position);

        lostPkgStream >> position >> startNum >> endNum;
        unSendPkgStruct.startPos = position;
        unSendPkgStruct.start = startNum;
        unSendPkgStruct.end = endNum;
        unSendPkgList.append(unSendPkgStruct);
    }
    this->sendUnfinishFile(fileName, unSendPkgList);

    if (isPause || isClientClose)
    {
        return;
    }

    lostPkgStream >> finishFlag >> eof;

    if (finishFlag == 0x01)
    {
//        qDebug() << "finishStream========================================"<< lostPkgStruct.lostPkgMap.count();

        //文件发送完成回复
        QByteArray finishDate;
        QDataStream finishStream(&finishDate,QIODevice::ReadWrite); //QIODevice::WriteOnly
        finishStream.setVersion(QDataStream::Qt_4_6);

        finishStream << qint16(0xFFFA);         //文件头
        finishStream << qint32(0x3e);           //帧总长度
        finishStream << qint8(0x16);            //cmd 接收文件
        finishStream << qint8(0x00);            //错误标志 暂时保留
        finishStream << qint8(0x02);            //开始标志 暂时保留

        finishStream.writeBytes(fileName.toLatin1().data(), 48);
        finishStream << qint32(0x00);
        finishStream << qint8(0xff);

        this->write(finishDate);
    }
    //如果数据包还未处理完成，那么将解析过的数据删除，继续解析剩下的数据
    if (receBytes.size() > pkglen)
    {

        isDataProUnfinish = false;
        receBytes.remove(0, pkglen);

        if (receBytes.size() ==  5)
        {
//            qDebug() << "....... isCmdErr .;....";
//            QFile file(ERR01PATH);
//            file.open(QFile::WriteOnly);
//            file.write(receBytes);
//            file.close();
        }

        this->processReceData(receBytes);
        return;
    }
}

/*******************************************
  功能：分析接收到的LCD命令包
  参数：receData，接收到的LCD命令包数据
  返回值：
  ******************************************/
void ClientService::analysisLcdCmd(const QByteArray& receData)
{
    qint32 len, slcdCount;
    qint16 header;
    qint8 cmd, order, eof;
    qint16 brightness;
    LcdBriLVStruct lvStruct[4];

    QList<PanelInfoStruct> infoList;
    QList<quint16> panelIDList;
    quint16 panelID = 0;
    qint32 panelCount = 0;
    panelIDList.clear();

    LcdSettingStruct lcdSettings;
    QByteArray receBytes = receData;
    QDataStream receStream(receBytes);
    receStream.setVersion(QDataStream::Qt_4_6);

    receStream >> header >> len >> cmd;

    if (cmd == qint8(0x31))
    {
        this->sendLcdIDList();
    } else if (cmd == qint8(0x34))
    {
        receStream >> brightness >> panelCount;
        lcdSettings.brightness = brightness;
        for(int i = 0; i < panelCount; i++)
        {
           receStream >> panelID;
           panelIDList.append(panelID);
        }
    } else if (cmd == qint8(0x36))
    {
//       receStream >> lcdK >> transformValue;
       for(int i = 0; i < 4; i++)
       {
           receStream >> lvStruct[i].lcdBirght >> lvStruct[i].envirStart >> lvStruct[i].envirEnd;
           lcdSettings.lvStruct[i] = lvStruct[i];
       }
    }  else if (cmd == qint8(0x3a))
    {
        receStream >> order >> panelCount;
        for(int i = 0; i < panelCount; i++)
        {
           receStream >> panelID;
           panelIDList.append(panelID);
        }
    } else if (cmd == qint8(0x3c))
    {
        receStream >> order;
    } else if (cmd == qint8(0x3f))
    {
        PanelInfoStruct panelInfo;
        receStream >> slcdCount;
        for(int i = 0; i < slcdCount; i++)
        {
            receStream >> panelInfo.panelID >> panelInfo.isCollect;
            infoList.append(panelInfo);
        }

    }
    receStream >> eof;

    if (eof != qint8(0xFF))
    {
        isDataProUnfinish = true;
        halfBytes.clear();
        receBytes.remove(0, len);
        halfBytes = receBytes;
        return;
    }

    if (cmd == qint8(0x31))
    {
        this->sendLcdIDList();
        emit getLcdSetting();
    } else if (cmd == qint8(0x34))
    {
//        qDebug() << "changeLcdBright" << lcdSettings.brightness;
        emit changeLcdBright(lcdSettings.brightness, panelIDList);
    } else if (cmd == qint8(0x36))
    {
        emit changeBriLv(lcdSettings);
    } else if (cmd == qint8(0x38))
    {
        sendLcdIDList();
        emit getLcdStatus();
        //查询背景灯光状态（0x63)
//        emit receLcdBackLightCtl(0x63);
        emit getLcdSetting();
    } else if (cmd == qint8(0x3a))
    {
        emit receLcdBackLightCtl(order, panelIDList);
    } else if (cmd == qint8(0x3c))
    {
        emit receQueryVideoStatus(order);
    } else if (cmd == qint8(0x3f))
    {
//        qDebug() << "111 ........>>" << 0x3f << cmd;
        emit receSlcdCollectState(infoList);
    }

    if (receBytes.size() > len)
    {
        receBytes.remove(0, len);
        this->processReceData(receBytes);
    }
}

/*******************************************
  功能：分析接收到的测试LCD命令数据
  参数：receData，接收到的数据
  返回值：
  ******************************************/
void ClientService::analysisChcekLcdData(const QByteArray& receData)
{
    qint16 header;
    qint32 len;
    qint8 cmd, eof;

    QByteArray receBytes = receData;
    QDataStream receStream(&receBytes,QIODevice::ReadOnly);
    receStream.setVersion(QDataStream::Qt_4_6);

    receStream >> header >> len >> cmd >> eof;

    if (eof != qint8(0xFF))
    {
        isDataProUnfinish = true;
        halfBytes.clear();
        halfBytes = receBytes;
        return;
    }


    if (cmd == 0x5F)
    {
        isCheckLcdMode = true;
    } else if (cmd == 0x5E)
    {
        isCheckLcdMode = false;
    }

    emit checkLcdCmd(cmd);

    if (receBytes.size() > len)
    {
        isDataProUnfinish = false;
        receBytes.remove(0, len);
        this->processReceData(receBytes);
        return;
    }
}

/*******************************************
  功能：分析接收到喂狗数据，如果数据正确，将发送一个喂狗信号
  参数：receData，接收到的喂狗数据
  返回值：
  ******************************************/
void ClientService::analysisFeedData(const QByteArray &receData)
{

    FreedDogStruct freedDogStruct;

    qint16 header, time, cpu, memory, hardDisk, retain;
    qint32 len;
    qint8 cmd, eof;

    QByteArray receBytes = receData;
    QDataStream feedStream(&receBytes,QIODevice::ReadOnly);
    feedStream.setVersion(QDataStream::Qt_4_6);

    feedStream >> header >> len >> cmd;
    feedStream >> time >> cpu >> memory >> hardDisk;

    for(int i = 0; i < 10; i++)
    {
        feedStream >> retain;
    }

    feedStream >> eof;

    //如果数据包此时只发送一半，那么将此数据包存贮到halfBytes中，
    //与下一个数据包合在一起再重新解析
    if (eof != qint8(0xFF))
    {
        isDataProUnfinish = true;
        halfBytes.clear();
        receBytes.remove(0, receBytes.size() - len);
        halfBytes = receBytes;

//        QFile file("D:/test11");
//        file.open(QFile::WriteOnly);
//        file.write(halfBytes);
//        file.close();
        return;
    }

    freedDogStruct.time = time;
    freedDogStruct.cpuLimmit = cpu;
    freedDogStruct.memoryLimmit = memory;
    freedDogStruct.hardDiskLimmit = hardDisk;

    emit receFeedData(freedDogStruct);

    //如果数据包还未处理完成，那么将解析过的数据删除，继续解析剩下的数据
    if (receBytes.size() > len)
    {
        isDataProUnfinish = false;
        receBytes.remove(0, len);
        this->processReceData(receBytes);
        return;
    }

}

/*******************************************
  功能：分析接收到的更新服务器数据，主要是更新的状态和发送新服务器文件的状态
  参数：receData，接收到的更新服务器数据
  返回值：
  ******************************************/
void ClientService::analysisupdateSerData(const QByteArray &receData)
{

//    qDebug() << "======== analysisupdateSerData ==============" << receData.size();

    QByteArray receBytes = receData;
    QDataStream receStream(&receBytes, QIODevice::ReadOnly);
    receStream.setVersion(QDataStream::Qt_4_6);

    qint16 header;
    qint32 len, fileCount;
    qint8 cmd, eof;

    receStream >> header >> len >> cmd >> fileCount >> eof;

    if (isUpdateSer)
    {
//        qDebug() << "analysisupdateSerData ===================";
        isUpdateSer = false;

        QString updatePath = tr("%1/%2").arg(g_installPath).arg(UPDATEPATH);
        QDir dir(updatePath);
        QFileInfoList infoList = dir.entryInfoList();
        if (infoList.count() - 2 >= fileCount)
        {
            emit updateService(1, fileCount);
        } else {
            emit updateService(-1, fileCount);
        }
    } else {

        emit updateService(0, fileCount);

        //此时开始是在更新服务器状态，将isUpdateSer置为true
        isUpdateSer = true;

//        QString debMsg = tr("analysisupdateSerData");
//        sendDebugMsg(debMsg);

    }
    //如果数据包还未处理完成，那么将解析过的数据删除，继续解析剩下的数据
    if (receData.size() > len)
    {
        receBytes.remove(0, len);
        this->processReceData(receBytes);
    }
}

/*******************************************
  功能：分析客户端检查连接状态发送来的数据
  参数：receData，接收到的下载完成数据
  返回值：
  ******************************************/
void ClientService::analysisCheckConnectDate(const QByteArray &receData)
{
    qint16 header;
    qint32 len;
    qint8 cmd, eof;

    QByteArray receBytes = receData;
    QDataStream receStream(&receBytes,QIODevice::ReadOnly);
    receStream.setVersion(QDataStream::Qt_4_6);

    receStream >> header >> len >> cmd >> eof;

    if (eof != qint8(0xFF))
    {
        isDataProUnfinish = true;
        halfBytes.clear();
        halfBytes = receBytes;
        return;
    }

    if (cmd == qint8(0xF5))
    {
        QByteArray sendBytes;

        QDataStream SendStream(&sendBytes, QIODevice::WriteOnly);
        SendStream.setVersion(QDataStream::Qt_4_6);
        SendStream << header << len << cmd << eof;

        if (len < this->write(sendBytes))
        {
            this->write(sendBytes);
        }
    }

    if (receBytes.size() > len)
    {
        isDataProUnfinish = false;
        receBytes.remove(0, len);
        this->processReceData(receBytes);
        return;
    }
}

/*******************************************
  功能：文件下载完成，下载完成时可能正确下载也可以出现错误
  参数：receData，接收到的下载完成数据
  返回值：
  ******************************************/
void ClientService::downLoadFinish(const QByteArray& receData)
{
//    qDebug() << "<<<<<<<<<<<<< downLoadFinish >>>>>>>>>>>>>>>";
    qint16 header;
    qint32 pkglen;
    quint32 fileLen;
    qint8 err, flag, cmd, eof;

    uint fileNameLen = 48;
    char *fileName = (char *)malloc(sizeof(char) * 49);


    QByteArray receBytes = receData;
    QDataStream receStream(receBytes);
    receStream.setVersion(QDataStream::Qt_4_6);


    receStream >> header >> pkglen >> cmd;
    receStream >> err >> flag;
    receStream.readBytes(fileName, fileNameLen);

    receStream >> fileLen;
    receStream >> eof;


    //如果是更新服务器，即检查错误，然后决定是否要重新下载服务文件
    if (isUpdateSer)
    {
        QString oldFileName = receInfoList[receInfoNum].file->fileName();
        QString newFileName = oldFileName.remove(".download");

        //如果文件名已经有了，那么在原有的文件名后面加上当前时间
        QFile file(newFileName);
        if (file.exists())
        {
            QTime time;
            QString appendName = time.currentTime().toString("hhssmm");
            int index = newFileName.lastIndexOf(".");
            newFileName = newFileName.insert(index, "-");
            newFileName = newFileName.insert(index+1, appendName);
        }

        receInfoList[receInfoNum].file->rename(newFileName);

        //发送更新结束信号(正确或者错误)
//        this->sendErrInfo(qint8(0xf1), (ERRENUM)err, 0);

        receInfoList[receInfoNum].file->close();
        receInfoList[receInfoNum].isFinish = true;
        delete receInfoList[receInfoNum].file;
        receInfoList.removeAt(receInfoNum);
    } else {
//        qDebug() << "finish 222 ===================+";
        //错误和正确处理方式不同
        if (err != 0)
        {
            this->sendErrInfo(qint8(0x12), (ERRENUM)err, receInfoList.at(receInfoNum).fileName);

            //如果出现错误，则将当前的文件下载相关信息保留
//            qDebug () << "down load err=============";
            receInfoList[receInfoNum].enmErr = (ERRENUM)err;
            receInfoNum ++;
        } else {
            //下载正确的话则将此次下载文件的信息从receInfoList中删除
            QString oldFileName = receInfoList[receInfoNum].file->fileName();
            QString newFileName = oldFileName.remove(".download");

            //如果文件名已经有了，那么在原有的文件名后面加上当前时间
            QFile file(newFileName);
            if (file.exists())
            {
                QTime time;
                QString appendName = time.currentTime().toString("hhssmm");
                int index = newFileName.lastIndexOf(".");
                newFileName = newFileName.insert(index, "-");
                newFileName = newFileName.insert(index+1, appendName);
            }

            receInfoList[receInfoNum].file->rename(newFileName);

            emit fileDownloadFinish(fileName);

            //如果没错误时，则将下载完成数据文件的相关信息清除
            receInfoList[receInfoNum].file->close();
            receInfoList[receInfoNum].isFinish = true;
            delete receInfoList[receInfoNum].file;
            receInfoList.removeAt(receInfoNum);
        }
    }

    //从重创建一个 下载文件相关信息结构体
    ReceInfoStruct receInfoStruct;
    receInfoStruct.file = new QFile(this);
    receInfoStruct.hasReceLen = 0;
    receInfoStruct.fileLen = 0;
    receInfoStruct.isFinish = false;
    receInfoStruct.pkgCount = 0;
    receInfoStruct.enmErr = TCPNOERR;
    receInfoList.append(receInfoStruct);


    //如果数据没处理完，继续处理
    if (!receStream.atEnd())
    {
        receBytes.remove(0, pkglen);
        this->processReceData(receBytes);
    }
}

/*******************************************
  功能：处理从客户端接收到的数据，根据不同命令值来分开处理
  参数：receData，接收到的数据
  返回值：
  ******************************************/
void ClientService::processReceData(const QByteArray& receData)
{
//    qDebug() << "processReceData=============================>" << receData.size();
    if (receData.size() < 7)
    {
        isDataProUnfinish = true;

        halfBytes.clear();
        halfBytes = receData;
        isEndErr = false;
        return ;
    }

//    QString debMsg;
    qint16 header;
    qint32 len, dataSize;
    qint8 cmd;


    char *fileName;
    uint fileNameLen = 48;
    //文件位置
    qint64 pos = 0;

    dataSize = receData.size();
    QByteArray receBytes = receData;

    //是否有数据包末读完，应该和最新接收的合并在一起
    if (isDataProUnfinish)
    {
        receBytes.insert(0, halfBytes);
        isDataProUnfinish = false;
        halfBytes.clear();
    }

    //检测包头，如果错误，把前面的数据全部丢掉
    QDataStream checkHeaderStream(&receBytes, QIODevice::ReadOnly);
    checkHeaderStream.setVersion(QDataStream::Qt_4_6);
    int removeCount = 0;
    while(header != qint16(0xFFFA))
    {
        checkHeaderStream >> header;
        removeCount = removeCount + 2;
        if (header == qint16(0xFFFA))
        {
            removeCount = removeCount - 2;
            if (removeCount != 0)
                receBytes.remove(0, removeCount);
        }
    }

    QDataStream receStream(&receBytes, QIODevice::ReadOnly);
    receStream.setVersion(QDataStream::Qt_4_6);
    //是否在读文件，是的话它的数据包大小的类型不同，一般只是quint8,读文件时则是qint32
    receStream >> header >> len >> cmd;

//    qDebug() << "receData:" << receData.size() << "receBytes:" << receBytes.size() << "processReceData=============>>len:" << len << "cmd:" << cmd;
//    debMsg = tr("%1 processReceData=============%2").arg(cmd).arg(receData.size());
//    sendDebugMsg(debMsg);

//    qDebug() << receBytes.size() << header << 0xFFFA << "444 =====>" << cmd << len;

    //根据相关的情况进行处理
    //0x01 客户端请求下载配置信息，服务端根据客户端要求发送配置信息，此处为服务端
    //0x04 客户端请求设置配置并发送配置数据，服务端根据数据设置相关配置，此处为服务端

    //0x03 客户端请求下载文件，服务端根据要求发送文件，此处为客户端
    //0x04 客户端发送文件过来，服务端接收客户端发送的文件，此处为客户端
    //0x05 客户端或者服务端最近一次发送文件操作完成，另一端相应进行完成收尾操作

    //0x06 客户端请求下载文件列表，服务端根据客户端要求发送文件列表，此处为服务端
    //0x07 客户端第一次发送 文件列表 过来，服务端接收，此处为服务端
    //0x08 客户端续发 文件列表 过来，服务端接收，此处为服务端

    //0xFD 客户端 服务器发送喂狗数据，服务端接收数据，此处为服务端

    if (header == qint16(0xFFFA))
    {
        switch(cmd)
        {
        case 0x01:     //接收到申请发送配置数据或者收到配置数据或者
            this->analysisConfigData(receData);
            break;
        case 0x02:
            break;
        case 0x03:      //发送文件
            break;
        case 0x04:
        case 0x07:
        case 0x08:
            this->analysisConfigData(receData);
            break;
        case 0x05:      //
            break;
        case 0x09:      //发送客户端请求的日记文件列表信息
            this->analysisNoteFileInfoData(receData);
            break;
        case 0x0A:      //第一次发送 文件列表
        case 0x0B:      //继续发送未发送 文件列表
            break;
        case 0x0C:      //文件列表已经发送完成
            break;
        case 0x0D:      //请求修改系统时间
            this->changeLocalDateTime(receData);
            break;
        case 0x11:      //发送文件
            fileName = (char *)malloc(sizeof(char) * 49);
            receStream.readBytes(fileName, fileNameLen);
            logger()->info("client:%1 download log:%2\n", this->peerAddress().toString(), fileName);
            receStream >> pos;
            this->sendFileData(fileName, pos);
            free(fileName);
            break;
        case 0x12:      //收到文件数据
            this->analysisFileData(receBytes);
            break;
        case 0x13:     //文件接收完成
            emit downLoadProgress(receInfoList[receInfoNum].fileName, receInfoList[receInfoNum].hasReceLen);
            this->downLoadFinish(receBytes);
            break;
        case 0x14:      //申请下载丢失的数据包
            this->analysisUnfinishPkg(receBytes);
            break;
        case 0x15:      //解析发送回来丢失的数据包
            this->analysisUnfinishPkg(receBytes);
            break;
        case 0x16:      //丢失数据包接收完成
            emit downLoadProgress(receInfoList[receInfoNum].fileName, receInfoList[receInfoNum].hasReceLen);
            this->downLoadFinish(receBytes);
            break;
        case 0x17:      // 暂停下载文件
            if (isPause == true)
            {
                isPause = false;
            } else {
                isPause = true;
            }
            if (receData.size() > 0x08)
            {
                this->processReceData(receBytes.remove(0, 8));
            }
            break;
        case 0x21:
            if (isWantEnvirBright == true)
            {
                isWantEnvirBright = false;
            } else {
                isWantEnvirBright = true;
            }
            if (receData.size() > 0x08)
            {
                this->processReceData(receBytes.remove(0, 8));
            }
            break;
        case qint8(0x31):
        case qint8(0x34):
        case qint8(0x36):
        case qint8(0x38):
        case qint8(0x3a):
        case qint8(0x3c):
        case qint8(0x3f):
            this->analysisLcdCmd(receData);
            break;
        case qint8(0x5F):
        case qint8(0x5E):
        case qint8(0x51):
        case qint8(0x52):
        case qint8(0x53):
        case qint8(0x54):
        case qint8(0x55):
            analysisChcekLcdData(receData);
            break;
        case qint8(0xF1):      //客户端请求开始升级服务端
//            debMsg = tr("cmd:%1 analysisupdateSerData processReceData=============%2").arg(cmd).arg(receData.size());
//            sendDebugMsg(debMsg);
//            qDebug() << debMsg;
            analysisupdateSerData(receBytes);
            break;
        case qint8(0xF2):      //发送更新状态
            break;
        case qint8(0xF4):      //客户端即将关闭
            if (isClientClose == true)
            {
                isClientClose = false;
            } else {
                isClientClose = true;
            }
            if (receData.size() > 0x08)
            {
                this->processReceData(receBytes.remove(0, 8));
            }
            break;
            break;
        case qint8(0xF5):
            this->analysisCheckConnectDate(receBytes);
        case qint8(0xFD):      //接收到喂狗数据
            this->analysisFeedData(receBytes);
            break;
        default:
//            debMsg = tr("cmd:%1 tcpClent cmd error==============").arg(cmd);
//            sendDebugMsg(debMsg);
//            qDebug() << "tcpClent cmd error==============" << cmd;
            break;
        }
    } else {
        //当数据头错误时，将数据写到错误文件中
//        debMsg = tr("header:%1 tcpClent header error==============").arg(header);
//        sendDebugMsg(debMsg);

//        qDebug() << "header:%1 tcpClent header error==============";
//        if (isEndErr)
//        {
//            isEndErr = false;
//            QFile file(ERR02PATH);
//            file.open(QFile::WriteOnly);
//            file.write(receBytes);
//            file.close();
//        }
    }
    return;
}

/*******************************************
  功能：断开连接槽函数，如果断开连接，将发送一个断开信息，把当前服务端的线程关闭
  参数：
  返回值：
  ******************************************/
void ClientService::disConnectSlot()
{
    logger()->info("client:%1 break out\n", this->peerAddress().toString());

    if (isCheckLcdMode)
        emit checkLcdCmd(0xFE);

    isClientClose = true;
    this->disconnectFromHost();
    this->close();
    emit disconnectSignal();
    this->deleteLater();
}

/*******************************************
  功能：发送环境光度
  参数：brightness,环境光度
  返回值：
  ******************************************/
void ClientService::sendEnvirBrightness(const qint16 brightness)
{
//    qDebug() << "sendEnvirBrightness" << brightness << isWantEnvirBright;
    //如果没有收到想到接收环境光度的請求，那么不发送环境光度
    if (!isWantEnvirBright)
    {
        return;
    }

    qint16 header, bright;
    qint32 len;
    qint8 cmd, eof;

    header = 0xFFFA;
    len = 0x0a;
    cmd = 0x22;
    bright = brightness;
    eof = 0xFF;

    QByteArray applyBytes;

    QDataStream applyStream(&applyBytes, QIODevice::WriteOnly);
    applyStream.setVersion(QDataStream::Qt_4_6);

    applyStream << header << len << cmd << bright << eof;

    //如果发送的数据数不对，则重新发送
    if (len > this->write(applyBytes))
    {
        this->write(applyBytes);
    }
}


/*******************************************
  功能：发送设置Lcd 转换值值状态
  参数：state,状态:成功或失败
  返回值：
  ******************************************/
void ClientService::sendSetLcdTraValueStatus(const qint8 state)
{
    //如果没有收到想到接收环境光度的請求，那么不发送环境光度
    if (!isWantEnvirBright)
    {
        return;
    }

    qint32 len;
    qint16 header;
    qint8 cmd, eof;

    QByteArray stateBytes;
    QDataStream stateStream(&stateBytes, QIODevice::WriteOnly);
    stateStream.setVersion(QDataStream::Qt_4_6);

    header = qint16(0xFFFA);
    len = qint32(0x09);
    cmd = qint8(0x37);
    eof = qint8(0xFF);

    stateStream << header << len << cmd << state << eof;

    this->write(stateBytes);
}

/*******************************************
  功能：设置LCD亮度等设置状态
  参数：state,状态:成功或失败
  返回值：
  ******************************************/
void ClientService::sendSetLcdSettingStatus(const qint8 state)
{
    //如果没有收到想到接收环境光度的請求，那么不发送环境光度
    if (!isWantEnvirBright)
    {
        return;
    }

    qint32 len;
    qint16 header;
    qint8 cmd, eof;

    QByteArray stateBytes;
    QDataStream stateStream(&stateBytes, QIODevice::WriteOnly);
    stateStream.setVersion(QDataStream::Qt_4_6);

    header = qint16(0xFFFA);
    len = qint32(0x09);
    cmd = qint8(0x35);
    eof = qint8(0xFF);

    stateStream << header << len << cmd << state << eof;

    this->write(stateBytes);
}

/*******************************************
  功能：发送当前LCD亮度对应的环境亮度
  参数：lcdSettings,状态结构体
  返回值：
  ******************************************/
void ClientService::sendLcdSetting(const LcdSettingStruct& lcdSettings)
{
    //如果没有收到想到接收环境光度的請求，那么不发送环境光度
    if (!isWantEnvirBright)
    {
        return;
    }

    qint16 header;
    qint32 len;
    qint8 cmd, eof;

    header = 0xFFFA;
    len = 0x22;
    cmd = 0x3E;
    eof = 0xFF;

    QByteArray applyBytes;

    QDataStream applyStream(&applyBytes, QIODevice::WriteOnly);
    applyStream.setVersion(QDataStream::Qt_4_6);

    applyStream << header << len << cmd << lcdSettings.brightness;

    for(int i = 0; i < 4; i++)
    {
       applyStream << lcdSettings.lvStruct[i].lcdBirght << lcdSettings.lvStruct[i].envirStart << lcdSettings.lvStruct[i].envirEnd;
    }


    applyStream << eof;

    //如果发送的数据数不对，则重新发送
    if (len > this->write(applyBytes))
    {
        this->write(applyBytes);
    }
}


/*******************************************
  功能：video状态
  参数：state,状态:成功或失败
  返回值：
  ******************************************/
void ClientService::sendVideoStatus(const QList<LCDSTATUS> &statusList, const bool isSendToTis)
{
    //如果没有收到想到接收环境光度的請求，那么不发送环境光度
    if (!isWantEnvirBright)
    {
        return;
    }

//    qDebug() << "sendVideoStatus===============>" << statusList.count();
//    for(int i = 0; i < statusList.count(); i++)
//    {
//        qDebug() << "i===>" << i << statusList.at(i).panelID << statusList.at(i).videoStatus;
//    }
    qint32 len, count;
    qint16 header;
    qint8 cmd, eof;

    QByteArray stateBytes;
    QDataStream stateStream(&stateBytes, QIODevice::WriteOnly);
    stateStream.setVersion(QDataStream::Qt_4_6);

    count = statusList.count();
    header = qint16(0xFFFA);
    len = qint32(0x0c + 4 * count);
    cmd = qint8(0x3D);
    eof = qint8(0xFF);



    stateStream << header << len << cmd << count;
    for(int i = 0; i< statusList.count(); i++)
    {
        stateStream << statusList.at(i).panelID << statusList.at(i).videoStatus;
    }

    stateStream << eof;
    this->write(stateBytes);
}

/*******************************************
  功能：发送服务关闭数据，通知客户端发送服务关闭数据，通知客户端
  参数：
  返回值：
  ******************************************/
void ClientService::sendServiceClose()
{
//    qDebug() << "===============sendServiceClose sendServiceClose======sendServiceClose=================>";
    qint16 header;
    qint32 pkglen;
    qint8  cmd, eof;

    header = qint16(0xFFFA);
    pkglen = qint32(0x08);
    cmd = qint8(0xF3);
    eof = qint8(0xFF);


    QByteArray sendBytes;
    QDataStream sendStream(&sendBytes, QIODevice::WriteOnly);
    sendStream.setVersion(QDataStream::Qt_4_6);


    sendStream << header << pkglen << cmd;
    sendStream << eof;
    this->write(sendBytes);
}


//发送系统状态
void ClientService::sendSystemState(const SystemState& state)
{
//    qDebug() << "=========sendSystemState=============" << state.cpuOccRate;
    QByteArray configBytes;
    ConfigStruct configStruct;

    QDataStream configStream(&configBytes,QIODevice::WriteOnly);

    configStream.setVersion(QDataStream::Qt_4_6);


    configStream << qint16(0xFFFA);            //文件头
    configStream << qint32(0x45);              //帧总长度
    configStream << qint8(0x06);               //配置信息命令,cmd

//    configStruct = configclass.getConfigStruct();

    qint16 year = configStruct.systemDate.year();
    qint8 month = configStruct.systemDate.month();
    qint8 day = configStruct.systemDate.day();

    qint8 hour = configStruct.systemTime.hour();
    qint8 minu = configStruct.systemTime.minute();
    qint8 second = configStruct.systemTime.second();
    qint8 scrollSpeed = configStruct.scrollSpeed;

    configStream << configStruct.defaultLv;

    for(int i = 0; i < 4; i++)
    {
        configStream << configStruct.lvStruct[i].lcdBirght << configStruct.lvStruct[i].envirStart << configStruct.lvStruct[i].envirEnd;
    }

    configStream << configStruct.carNum;
    configStream << configStruct.carSide;
    configStream << year << month << day << hour << minu << second;
    configStream << scrollSpeed;

    configStream << configStruct.cpuLimmit;
    configStream << configStruct.memoryLimmit;
    configStream << configStruct.hardDiskLimmit;
    configStream << configStruct.limmit;

    configStream << quint8(state.cpuOccRate);
    configStream << quint8(state.memOccRate);
    configStream << quint8(state.hardDiskOccRate);

    //保留数据位12
    for (int i = 0; i < 6; i++)
    {
        configStream << qint16(0);
    }

    configStream << qint8(0xFF);         //帧尾

    //如果发送数据小于要发送数据包大小，那么得重新发送
    if (configBytes.size() < (this->writeBytes(configBytes)))
    {
        this->write(configBytes);
    }
//    qDebug() << configBytes.size() << "ClientService===================>>" << state.cpuOccRate << state.memOccRate << state.hardDiskOccRate;
}

void ClientService::sendLcdAnswerStatus(QList<LCDSTATUS> status)
{
    //0x0E　发送设置lcd亮度或者背景灯状态的回复,查询LCD屏状态

    QByteArray configBytes;
    QDataStream configStream(&configBytes,QIODevice::WriteOnly);
    qint32 statuCount;
    qint32 statuType;
    qint16 panelID, lcdStatu, birghtness;
    qint8 blStatu;
    qint32 size;


    if (status.count() <= 0)
    {
        return;
    }
    statuCount = status.count();
    statuType = status.at(0).enLcdStatuType;

    configStream.setVersion(QDataStream::Qt_4_6);

    //如果cmd为0x01则是发送服务的配置，如果是0X02则是发送服务器设置成功信息
    if (statuType == LCDSTATU_BRIGHTNESS_TYPE)
    {
        size = 0x10 + statuCount * 6;
    } else {
        size = 0x10 + statuCount * 5;
    }
    configStream << qint16(0xFFFA);                     //文件头
    configStream << qint32(size);        //帧总长度
    configStream << qint8(0x0E);                        //配置信息命令
    configStream << statuType;
    configStream << statuCount;

    for(int i = 0; i < statuCount; i++)
    {
        panelID = status.at(i).panelID;
        lcdStatu = status.at(i).videoStatus;
        if (statuType == LCDSTATU_BRIGHTNESS_TYPE)
        {
            birghtness = status.at(i).brightness;
            configStream << panelID << lcdStatu << birghtness;
        } else {
            blStatu = status.at(i).blStatus;
            configStream << panelID << lcdStatu << blStatu;
        }
    }

    configStream << qint8(0xFF);         //帧尾

    int writeSize;
    writeSize = this->writeBytes(configBytes);

    //如果发送数据小于要发送数据包大小，那么得重新发送
//    if (configBytes.size() < (this->writeBytes(configBytes)))
//    {
//        writeSize = this->write(configBytes);
//    }
}
